package com.clp.protocol.core.pdu.nbytepdu;

import lombok.Getter;

import java.util.function.Consumer;

@Getter
public abstract class BaseNBytePduClip<PC extends BaseNBytePduClip<PC>> implements NBytePduClip<PC> {
    protected volatile ToStringFormat toStringFormat = ToStringFormat.DEFAULT_FORMAT;

    @Override
    public ToStringFormat getToStringFormat() {
        return toStringFormat;
    }

    /**
     * 将该帧及所有子帧的打印格式设成指定打印格式
     * @param toStringFormat 指定打印格式
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public PC setToStringFormat(ToStringFormat toStringFormat) {
        checkValid();
        this.toStringFormat = toStringFormat;
        forEachAllLevelChild(baseFrameClip -> baseFrameClip.setToStringFormat(toStringFormat));
        return (PC) this;
    }

    /**
     * 遍历所有级别下的每一个子帧片段：子帧、孙子帧、等等
     * @param consumer
     */
    protected void forEachAllLevelChild(Consumer<BaseNBytePduClip<?>> consumer) {
        Consumer<BaseNBytePduClip<?>> tConsumer = new Consumer<BaseNBytePduClip<?>>() {
            @Override
            public void accept(BaseNBytePduClip<?> baseFrameClip) {
                consumer.accept(baseFrameClip);
                baseFrameClip.forEachOneLevelChild(this);
            }
        };
        forEachOneLevelChild(tConsumer);
    }

    /**
     * 遍历本级下的每一个子帧片段（排除非子帧片段的数据）
     * @param consumer
     * @return
     */
    protected abstract void forEachOneLevelChild(Consumer<BaseNBytePduClip<?>> consumer);

    @Override
    public String toString() {
        return getToStringFormat().format(this);
    }
}
